/*
	界面管理
*/
/* ---------------------- */

import SceneUsr from "../../stage3d/sceneusr";
import EditorStage from "../../stage3d/editorstage";
import AutoGoStage from "../../stage3d/autogo"
//extend 
import SGui from "../gui/sgui";
//debug 
import { Stats } from "../stats";
import { DEBUG } from "../../relconf";
//fairyui 
import * as fgui from "fairygui-three"



const WIDTH = 1920, HEIGHT = 1080;
const SCENE_MODE = "horizontal"

var camera, scene, renderer;                    //threejs基础三变量
var hud_camera, hud_scene, hud_guiroot;         //自己创建的hud相关的变量
var editorstage, autostage;                     //自定义舞台
var stats;                                      //调试state.js

const appendDOM = function (render_) {
    var dom = document.createElement("div")
    dom.appendChild(render_.domElement);
    document.body.appendChild(dom)
    window.addEventListener('resize', () => {
        render_.setSize(window.innerWidth, window.innerHeight)
        fgui.UIContentScaler.scaleWithScreenSize(window.innerWidth, window.innerHeight, fgui.ScreenMatchMode.MatchWidthOrHeight);
    }, false);
    renderer.setSize(window.innerWidth, window.innerHeight)
}

function init() {
    camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 20000);
    // camera.position.z = 1;
    camera.position.set(0, 100, 400);

    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize(WIDTH, HEIGHT);
    scene = new SceneUsr(camera, renderer);

    //dom
    appendDOM(renderer)
    return scene;
}

function init_by_full(sjson, cameraname, cb) {
    const l_file = new THREE.FileLoader();
    l_file.load(sjson, (text) => {
        //renderer
        renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setPixelRatio(window.devicePixelRatio)
        renderer.outputEncoding = THREE.sRGBEncoding
        renderer.autoClear = false
        //dom
        appendDOM(renderer)
        const scene_json = JSON.parse(text);
        const loader = new THREE.ObjectLoader();
        scene = loader.parse(scene_json)
        camera = scene.getObjectByName(cameraname)
        camera.aspect = WIDTH / HEIGHT
        camera.updateProjectionMatrix()
        autostage = new AutoGoStage(scene, camera, renderer);
        cb();
    })
}

function init_by_editor(sjson, cameraname, cb) {
    const l_file = new THREE.FileLoader();
    l_file.load(sjson, (text) => {
        init_hud();
        //renderer
        renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setPixelRatio(window.devicePixelRatio)
        renderer.outputEncoding = THREE.sRGBEncoding
        renderer.autoClear = false
        /* 
        这里的autoclear 
        是为了兼容init_hud来的 为了同时渲染两个摄像机
        autoclear必须为false, 更改为手动clear 场景
         */
        //dom
        appendDOM(renderer)
        const scene_json = JSON.parse(text);
        const loader = new THREE.ObjectLoader();
        scene = loader.parse(scene_json)
        camera = scene.getObjectByName(cameraname)
        camera.aspect = WIDTH / HEIGHT
        camera.updateProjectionMatrix()
        editorstage = new EditorStage(scene, camera, renderer, hud_camera);
        cb();
    })
}

function init_hud() {
    hud_camera = new THREE.OrthographicCamera(-WIDTH / 2, WIDTH / 2, HEIGHT / 2, - HEIGHT / 2, 1, 1000);
    hud_scene = new THREE.Scene();
    //root position like cocos2dx
    let gui_group = new THREE.Group();
    gui_group.name = "GUI";
    hud_scene.add(gui_group);
    gui_group.position.x = -WIDTH / 2;
    gui_group.position.y = -HEIGHT / 2;
    gui_group.position.z = -1;
    hud_guiroot = gui_group;
}

function animate() {
    if (DEBUG) stats.begin();
    if (scene && scene.update) {
        scene.update();
    }
    renderer.render(scene, camera);

    if (DEBUG) stats.end();
    requestAnimationFrame(animate);
}

function animate_editor() {
    if (DEBUG) stats.begin();
    if (editorstage && editorstage.update) {
        editorstage.update()
    }
    renderer.clear();
    renderer.render(scene, camera);
    renderer.clearDepth();
    renderer.render(hud_scene, hud_camera);

    if (DEBUG) stats.end();
}

function animate_full() {
    if (DEBUG) stats.begin();
    fgui.Stage.update()
    if (autostage && autostage.update) {
        autostage.update()
    }
    renderer.clear()
    renderer.render(scene, camera)
    renderer.clearDepth()
    renderer.render(fgui.Stage.scene, fgui.Stage.camera);

    if (DEBUG) stats.end();
}
/* ---------------------- */

export default class StagerMgr {
    static getInstance() {
        if (!this._inc) {
            this._inc = new StagerMgr();
            this._sceneobj = undefined;
            this._viewobj = undefined;

            this._win1 = undefined;
            this._win2 = undefined;


            this.VIEW_MAP = {}
            this.WIN_MAP = {}
            this._inc._init_debug();
        }
        return this._inc;
    }

    set viewClsMap(map) {
        /* ex: */
        /* const VIEW_MAP = {
            "viewstart": ViewStart,
            "viewfight": ViewFight,
            };
        */
        this.VIEW_MAP = map
    }

    set winClsMap(map) {
        /* ex: */
        /* const VIEW_MAP = {
            "WinAlert":WinAlert
            };
        */
        this.WIN_MAP = map
    }

    get camera() {
        return camera;
    }

    get dom() {
        return renderer.domElement;
    }

    _init_debug() {
        if (DEBUG) {
            stats = new Stats();
            stats.showPanel(0);
            document.body.appendChild(stats.dom);
        }
    }

    showScene() {
        init();
        animate();
        this._sceneobj = scene;
    }

    showEditorScene(sjson) {
        init_by_editor(sjson, "camera_rel", () => {
            renderer.setAnimationLoop(animate_editor)
            SGui.bindRoot(scene, hud_guiroot);
            this._sceneobj = scene;
        });
    }

    shwoFullScene(sjson) {
        init_by_full(sjson, "camera_rel", () => {
            renderer.setAnimationLoop(animate_full)
            fgui.Stage.init(renderer, { sceneMode: SCENE_MODE })
            fgui.Stage.scene = new THREE.Scene()
            fgui.UIContentScaler.scaleWithScreenSize(1920, 1080, fgui.ScreenMatchMode.MatchWidthOrHeight);
            this._sceneobj = scene;
        });
    }

    showView(viewname) {
        if (this._sceneobj) {
            this._sceneobj.showView(1, this.VIEW_MAP[viewname.toLowerCase()]);
        }
    }

    showWin(winname, winlv) {
        winlv = winlv || 1;
        if (this._sceneobj) {
            this._sceneobj.showWin(winlv, this.WIN_MAP[winname.toLowerCase()]);
        }
    }

    clearView() {
        if (this._sceneobj) {
            this._sceneobj.closeView();
            this._sceneobj.closeWin();
        }
    }
}
